use crate::models::{Message, MessageEvent};
use crate::AppState;
use anyhow::{anyhow, Result};
use log::{error, info, warn, debug, trace};
use mailin::AuthMechanism;
// 明确导入Response（避免命名冲突）
use mailin::Response;
use mailin_embedded::{Handler, SslConfig};
use std::io;
use std::net::SocketAddr;
use std::sync::Arc;

/// SMTP服务器封装（内部持有mailin_embedded服务器实例）
pub struct Server(mailin_embedded::Server<MyHandler>);

impl Server {
    /// 启动SMTP服务器，处理连接和邮件接收
    pub async fn serve(self) -> Result<()> {
        info!("SMTP服务器启动中，等待邮件连接...");

        match self.0.serve() {
            Ok(_) => {
                info!("SMTP服务器已正常停止");
                Ok(())
            }
            Err(e) => {
                error!("SMTP服务器运行异常终止: {}", e);
                Err(anyhow!("SMTP server failed to run: {}", e))
            }
        }
    }
}

/// SMTP服务器构建器（用于配置服务器参数）
pub struct Builder {
    state: Option<Arc<AppState>>,
    ssl_config: SslConfig,
    socket: Option<SocketAddr>,
    auth: bool,
}

impl Default for Builder {
    fn default() -> Self {
        Self::new()
    }
}

impl Builder {
    /// 创建空的构建器实例
    pub fn new() -> Self {
        Builder {
            state: None,
            ssl_config: SslConfig::None,
            socket: None,
            auth: false,
        }
    }

    /// 绑定应用全局状态（必须配置）
    pub fn with_state(mut self, state: Arc<AppState>) -> Self {
        self.state = Some(state);
        self
    }

    /// 启用/禁用SMTP认证
    pub fn with_auth(mut self, value: bool) -> Self {
        self.auth = value;
        self
    }

    /// 配置SSL（需同时提供证书和密钥路径）
    pub fn with_ssl(mut self, cert_path: Option<String>, key_path: Option<String>) -> Self {
        match (cert_path, key_path) {
            (Some(cert), Some(key)) => {
                self.ssl_config = SslConfig::SelfSigned {
                    cert_path: cert.clone(),
                    key_path: key.clone(),
                };
                info!("SMTP SSL配置完成: 证书={}, 密钥={}", cert, key);
            }
            (Some(_), None) => {
                warn!("SMTP SSL配置无效: 仅提供证书路径，缺少密钥路径（将禁用SSL）");
            }
            (None, Some(_)) => {
                warn!("SMTP SSL配置无效: 仅提供密钥路径，缺少证书路径（将禁用SSL）");
            }
            (None, None) => {
                debug!("SMTP未配置SSL，将使用纯文本传输");
            }
        }
        self
    }

    /// 绑定服务器监听地址
    pub fn bind(mut self, socket: SocketAddr) -> Self {
        self.socket = Some(socket);
        self
    }

    /// 构建SMTP服务器实例（参数验证+配置应用）
    pub fn build(self) -> Server {
        // 验证必要参数：应用状态
        let state = match self.state {
            Some(s) => s,
            None => {
                error!("SMTP构建失败: 未配置AppState（必须通过with_state绑定）");
                panic!("SMTP Builder requires a valid AppState");
            }
        };

        // 验证必要参数：监听地址
        let socket = match self.socket {
            Some(s) => s,
            None => {
                error!("SMTP构建失败: 未配置监听地址（必须通过bind绑定）");
                panic!("SMTP Builder requires a valid SocketAddr");
            }
        };

        // SslConfig无Debug，用文字描述替代{:?}
        let ssl_desc = match &self.ssl_config {
            SslConfig::None => "None",
            SslConfig::SelfSigned { .. } => "SelfSigned",
            _ => "Unknown",
        };
        debug!(
            "SMTP构建参数确认: 地址={}, 认证={}, SSL类型={}",
            socket, self.auth, ssl_desc
        );

        // 创建邮件处理逻辑实例
        let handler = MyHandler {
            data: Vec::new(),
            state: state.clone(),
        };

        // 初始化服务器并应用配置
        let mut server = mailin_embedded::Server::new(handler);

        // 应用SSL配置
        match server.with_ssl(self.ssl_config) {
            Ok(_) => debug!("SMTP SSL配置已生效"),
            Err(e) => {
                error!("SMTP SSL配置失败: {}", e);
                panic!("SMTP SSL config error: {}", e);
            }
        }

        // 绑定监听地址
        match server.with_addr(socket) {
            Ok(_) => debug!("SMTP已绑定到地址: {}", socket),
            Err(e) => {
                error!("SMTP地址绑定失败: {}（错误: {}）", socket, e);
                panic!("SMTP bind error: {}", e);
            }
        }

        // 配置认证机制
        if self.auth {
            server.with_auth(AuthMechanism::Plain);
            // 验证认证所需的用户名/密码是否存在
            if state.smtp_auth_username.is_none() || state.smtp_auth_password.is_none() {
                warn!("SMTP已启用认证，但未配置用户名/密码（所有认证请求将失败）");
            }
            info!("SMTP已启用Plain认证机制");
        } else {
            warn!("SMTP未启用认证（生产环境建议启用，防止滥用）");
        }

        // 构建完成日志
        info!("SMTP服务器构建成功，监听地址: smtp://{}", socket);
        Server(server)
    }
}

/// SMTP邮件处理逻辑（实现mailin_embedded的Handler trait）
#[derive(Clone)]
pub struct MyHandler {
    /// 临时存储接收中的邮件数据
    pub data: Vec<u8>,
    /// 应用全局状态（用于存储邮件和广播事件）
    pub state: Arc<AppState>,
}

impl Handler for MyHandler {
    /// 接收邮件数据片段（逐段接收）
    fn data(&mut self, buf: &[u8]) -> io::Result<()> {
        // Cow<str>转换为字符迭代器后截取预览
        let preview = String::from_utf8_lossy(buf)
            .chars()
            .take(50)
            .collect::<String>();
        trace!(
            "SMTP接收邮件数据: 片段长度={}字节，内容预览={:?}",
            buf.len(), preview
        );
        self.data.extend_from_slice(buf);
        Ok(())
    }

    /// 邮件数据接收完成（触发解析、存储和事件广播）
    fn data_end(&mut self) -> Response {
        info!("SMTP接收完整邮件，总大小={}字节，开始处理", self.data.len());

        // 1. 解析邮件数据
        let message = match Message::from(&self.data) {
            Ok(msg) => {
                // 用正确字段名（sender/recipients），ID为Option则用{:?}格式化
                debug!(
                    "邮件解析成功: 发件人={:?}, 收件人={:?}, 主题={:?}, 邮件ID={:?}",
                    msg.sender, msg.recipients, msg.subject, msg.id
                );
                msg
            }
            Err(e) => {
                // 截取邮件数据预览
                let preview = String::from_utf8_lossy(&self.data)
                    .chars()
                    .take(100)
                    .collect::<String>();
                error!(
                    "邮件解析失败: 错误={}，数据预览={:?}",
                    e, preview
                );
                self.data.clear();
                // 修复1：用Response::custom替代new（mailin 0.6.x API）
                return Response::custom(400, "Bad Request: Invalid email format".to_string());
            }
        };

        // 2. 存储邮件到全局存储
        let stored_msg = match self.state.storage.write() {
            Ok(mut storage) => {
                let msg = storage.add(message);
                // 修复2：Option<usize>用{:?}格式化（或处理None场景）
                info!("邮件存储成功: 邮件ID={:?}", msg.id);
                msg
            }
            Err(e) => {
                error!("获取存储写锁失败: 错误={}", e);
                self.data.clear();
                // 修复3：用Response::custom构造500错误
                return Response::custom(500, "Internal Server Error: Storage lock failed".to_string());
            }
        };

        // 3. 广播邮件新增事件
        let event = MessageEvent {
            event_type: "add".to_string(),
            message: stored_msg.clone(),
        };
        match serde_json::to_string(&event) {
            Ok(event_str) => {
                match self.state.channel.send(event_str) {
                    Ok(_) => {
                        // 修复4：Option<usize>用{:?}格式化
                        debug!("邮件事件广播成功: 邮件ID={:?}", stored_msg.id)
                    }
                    Err(e) => warn!("邮件事件广播失败: 错误={}", e),
                }
            }
            Err(e) => {
                error!("邮件事件序列化失败: 错误={}", e);
            }
        }

        // 重置缓冲区
        self.data.clear();
        info!("邮件处理完成，返回OK响应");
        // 使用mailin内置OK响应（确保导入正确）
        mailin::response::OK
    }

    /// 处理SMTP Plain认证（验证用户名密码）
    fn auth_plain(
        &mut self,
        _authorization_id: &str,
        authentication_id: &str,
        password: &str,
    ) -> Response {
        debug!(
            "收到SMTP认证请求: 用户名={}，密码长度={}字节",
            authentication_id,
            password.len()
        );

        // 验证服务器是否配置了认证凭据
        let (config_user, config_pass) = match (
            self.state.smtp_auth_username.as_deref(),
            self.state.smtp_auth_password.as_deref(),
        ) {
            (Some(u), Some(p)) => (u, p),
            _ => {
                warn!("认证请求被拒绝: 服务器未配置用户名/密码");
                return mailin::response::INVALID_CREDENTIALS;
            }
        };

        // 验证凭据是否匹配
        if authentication_id == config_user && password == config_pass {
            info!("SMTP认证成功: 用户名={}", authentication_id);
            mailin::response::AUTH_OK
        } else {
            warn!("SMTP认证失败: 用户名或密码错误（尝试的用户名={}）", authentication_id);
            mailin::response::INVALID_CREDENTIALS
        }
    }
}
